<?php

namespace App\Trip\Epidemic\Juhe;

use Exception;
use GuzzleHttp\Exception\GuzzleException;
use Illuminate\Support\Facades\Cache;

/**
 * 查询出行防疫政策
 */
class Policy extends JuheAbstract
{
    public array   $risk_levels
                        = [
            0 => "暂无",
            1 => '低风险',
            2 => '中风险',
            3 => '高风险',
            4 => '部分地区中风险',
            5 => '部分地区高风险',
            6 => '部分地区中、高风险',
        ];
    private string $url = 'http://apis.juhe.cn/springTravel/query';

    /**
     * @throws GuzzleException
     * @throws Exception
     */
    public function query($param)
    {
        $from = $param['from'];
        $to   = $param['to'];

        if ($from == 0 && $to == 0) {
            throw new Exception("当前城市出入城市不存在防疫政策");
        }
        if ($from == 0) {
            $from = $to;
        }
        if ($to == 0) {
            $to = $from;
        }
        // 缓存每个城市的查询服务结果
        $cache_from_key = "Epidemic:policy_city:{$from}";
        $cache_to_key   = "Epidemic:policy_city:{$to}";
        $url            = sprintf($this->url."?key=%s&from=%d&to=%d", $this->key, $from, $to);
        $cache_key      = "Epidemic:policy:".md5($url);
        if ($this->refresh || !Cache::has($cache_key) || !Cache::has($cache_from_key) || !Cache::has($cache_to_key)) {
            $response = $this->client->get($url);
            $contents = $response->getBody()->getContents();
            $res      = json_decode($contents, true);
            if (isset($res['error_code']) && $res['error_code'] == 0) {
                if (isset($res["result"]["from_info"])) {
                    //  high_in_desc  高风险地区，进入政策描述
                    //  low_in_desc	  低风险地区，进入政策描述
                    $from_data = [
                        "high_in_desc" => trim($res["result"]["from_info"]["high_in_desc"] ?? ''),
                        "low_in_desc"  => trim($res["result"]["from_info"]["low_in_desc"] ?? ''),
                        "out_desc"     => trim($res["result"]["from_info"]["out_desc"] ?? ''),
                        "risk_level"   => trim($res["result"]["from_info"]["risk_level"] ?? ''),
                    ];
                    Cache::put($cache_from_key, $from_data, 3 * config('trip.ttl.day'));
                }
                if (isset($res["result"]["from_info"])) {
                    $to_data = [
                        "high_in_desc" => trim($res["result"]["to_info"]["high_in_desc"] ?? ''),
                        "low_in_desc"  => trim($res["result"]["to_info"]["low_in_desc"] ?? ''),
                        "out_desc"     => trim($res["result"]["to_info"]["out_desc"] ?? ''),
                        "risk_level"   => trim($res["result"]["to_info"]["risk_level"] ?? ''),
                    ];
                    Cache::put($cache_to_key, $to_data, 3 * config('trip.ttl.day'));
                }
                Cache::put($cache_key, 1, config('trip.ttl.day'));
            } else {
                $this->circuit_breaker = true;
            }
        }
        $this->result = [
            "from_info" => Cache::get($cache_from_key),
            "to_info"   => Cache::get($cache_to_key),
        ];
        return $this;
    }

    public function getFromInDesc(): string
    {
        $desc = "";
        if (isset($this->result['from_info'])) {
            $desc .= $this->result['from_info']['high_in_desc'] ?? '';
            $desc .= $this->result['from_info']['low_in_desc'] ?? '';
        }
        return $desc;
    }

    public function getFromOutDesc(): string
    {
        $desc = "";
        if (isset($this->result['from_info'])) {
            $desc .= $this->result['from_info']['out_desc'] ?? '';
        }
        return $desc;
    }

    public function getFromRiskLevel()
    {
        return $this->result['from_info']['risk_level'] ?? 0;
    }

    public function getToInDesc(): string
    {
        $desc = "";
        if (isset($this->result['from_info'])) {
            $desc .= $this->result['to_info']['high_in_desc'] ?? '';
            $desc .= $this->result['to_info']['low_in_desc'] ?? '';
        }
        return $desc;
    }

    public function getToOutDesc(): string
    {
        $desc = "";
        if (isset($this->result['from_info'])) {
            $desc .= $this->result['to_info']['out_desc'] ?? '';
        }
        return $desc;
    }

    public function getToRiskLevel()
    {
        return $this->result['to_info']['risk_level'] ?? 0;
    }

    public function getResult(): array
    {
        return $this->result;
    }

    public function getRiskLevel(): array
    {
        return $this->risk_levels;
    }
}